package com.cjk.console.service;

import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.cjk.console.model.Callback;
import com.cjk.console.model.DeviceInfo;
import com.cjk.console.request.DeviceRequest;
import com.cjk.foundation.commons.BusinessException;
import com.cjk.foundation.commons.response.PageResponse;
import com.cjk.foundation.commons.response.Response;
import com.cjk.foundation.dao.AppVersionDao;
import com.cjk.foundation.dao.DeviceDao;
import com.cjk.foundation.dao.DeviceMgtLogDao;
import com.cjk.foundation.dao.EmployeeDao;
import com.cjk.foundation.dao.GroupDao;
import com.cjk.foundation.entity.AppVersionEntity;
import com.cjk.foundation.entity.DeviceEntity;
import com.cjk.foundation.entity.DeviceMgtLogEntity;
import com.cjk.foundation.entity.EmployeeEntity;
import com.cjk.foundation.entity.GroupEntity;
import com.cjk.foundation.enums.ConfStatus;
import com.cjk.foundation.enums.DeviceMgtType;
import com.cjk.foundation.enums.DeviceStatus;
import com.cjk.foundation.enums.DeviceType;

@Service
public class DeviceServiceImpl implements DeviceService {

	private static final Logger LOGGER = LoggerFactory.getLogger(DeviceServiceImpl.class);
	
	@Autowired
	private AppVersionDao appVersionDao;

	@Autowired
	private EmployeeDao employeeDao;

	@Autowired
	private GroupDao groupDao;

	@Autowired
	private DeviceDao deviceDao;

	@Autowired
	private DeviceMgtLogDao deviceMgtLogDao;

	@Autowired
	private DeviceOperateService deviceOperateService;

	@Override
	public void addDevice(DeviceRequest request, Integer userId) {
		DeviceEntity deviceExistEntity = deviceDao.selectBySn(request.getSn(), null);
		if (deviceExistEntity != null) {
			EmployeeEntity employeeEntity = employeeDao.selectById(userId);
			throw new BusinessException("设备[" + request.getSn() + "]已经在账号[" + employeeEntity.getUsername() + "]的["
					+ deviceExistEntity.getGroupName() + "]分组下");
		}
		DeviceType deviceType = request.getDeviceType() == null ? DeviceType.UNKNOW : request.getDeviceType();
		DeviceEntity deviceEntity = new DeviceEntity();
		deviceEntity.setSn(request.getSn());
		deviceEntity.setUserId(userId);
		deviceEntity.setGroupId(request.getGroupId());
		deviceEntity.setAliasName(request.getAliasName());
		deviceEntity.setDeviceClass(request.getDeviceClass());
		deviceEntity.setDeviceType(deviceType);
		deviceEntity.setStatus(DeviceStatus.NEVER_ONLINE);
		ConfStatus confStatus = DeviceType.SERVER.equals(deviceType) ? ConfStatus.NOT_SYNC : null;
		deviceEntity.setConfStatus(confStatus);
		deviceEntity.setRoom(request.getRoom());
		deviceDao.insert(deviceEntity);
	}

	@Override
	public PageResponse getDeviceList(DeviceRequest request, Integer userId) {
		GroupEntity groupEntity = null;
		if (request.getGroupId() != null) {
			groupEntity = groupDao.selectById(request.getGroupId());
		} else {
			groupEntity = groupDao.selectRootGroup(userId);
		}
		List<Integer> groupIds = groupDao.selectIdsByParentId(groupEntity.getRgt(), groupEntity.getLft(), userId);
		List<DeviceEntity> deviceEntities = deviceDao.selectListByCondition(userId, groupIds, request.getDeviceType(),
				request.getStatus(), request.getKeywords(), request.getPage(), request.getPageSize());
		if (CollectionUtils.isEmpty(deviceEntities)) {
			return PageResponse.success(0, request.getPageSize(), new ArrayList<>());
		}
		for (DeviceEntity deviceEntity : deviceEntities) {
			deviceEntity.setStatusDesc(deviceEntity.getStatus().getLabel());
			String confDesc = deviceEntity.getConfStatus() != null ? deviceEntity.getConfStatus().getLabel() : "";
			deviceEntity.setConfStatusDesc(confDesc);
			deviceEntity.setDeviceTypeDesc(deviceEntity.getDeviceType().getLabel());
			if (request.getDeviceType().equals(DeviceType.STB)) {
				AppVersionEntity appVersionEntity = appVersionDao.selectBySn(deviceEntity.getSn());
				if (appVersionEntity != null) {
					deviceEntity.setLauncherVersion(appVersionEntity.getLauncherVersion());
					deviceEntity.setLiveVersion(appVersionEntity.getLiveVersion());
					deviceEntity.setMovieVersion(appVersionEntity.getMovieVersion());
				}
			}
		}
		final Integer total = deviceDao.countByCondition(userId, groupIds, request.getDeviceType(), request.getStatus(),
				request.getKeywords());
		return PageResponse.success(total, request.getPageSize(), deviceEntities);
	}

	@Override
	public Response getDevice(String sn, Integer userId) {
		DeviceEntity deviceEntity = deviceDao.selectBySn(sn, userId);
		deviceEntity.setStatusDesc(deviceEntity.getStatus().getLabel());
		deviceEntity.setConfStatusDesc(deviceEntity.getConfStatus().getLabel());
		deviceEntity.setDeviceTypeDesc(deviceEntity.getDeviceType().getLabel());
		return Response.success(deviceEntity);
	}

	@Override
	public Response delDevice(DeviceRequest request, Integer userId) {
		if (CollectionUtils.isEmpty(request.getSns())) {
			throw new BusinessException("请至少选择一台设备");
		}
		deviceDao.deleteBySns(request.getSns(), userId);
		return Response.success();
	}

	// 服务器的inform事件
	@Transactional
	@Override
	public void updateDeviceByInform(DeviceInfo deviceInfo) {
		DeviceEntity deviceEntity = deviceDao.selectBySn(deviceInfo.getSn(), null);
		if (deviceEntity == null) {
			LOGGER.error("update device by inform device {} is not exist", deviceInfo.getSn());
			return;
		}
		DeviceEntity updateDeviceEntity = new DeviceEntity();
		updateDeviceEntity.setSn(deviceInfo.getSn());
		updateDeviceEntity.setAliasName(deviceInfo.getAliasName());
		updateDeviceEntity.setDeviceClass(deviceInfo.getDeviceClass());
		updateDeviceEntity.setDeviceType(deviceInfo.getDeviceType());
		if (deviceEntity.getStatus().equals(DeviceStatus.NEVER_ONLINE)) {
			updateDeviceEntity.setFirstInform(deviceInfo.getUploadTime());
			deviceMgtLogDao.insert(deviceEntity.getUserId(), deviceEntity.getGroupId(), deviceEntity.getSn(),
					DeviceMgtType.FIRST_ONLINE, DeviceMgtType.FIRST_ONLINE.getLabel());
		} else if (deviceEntity.getStatus().equals(DeviceStatus.OFFLINE)) {
			deviceMgtLogDao.insert(deviceEntity.getUserId(), deviceEntity.getGroupId(), deviceEntity.getSn(),
					DeviceMgtType.ONLINE, DeviceMgtType.ONLINE.getLabel());
		}
		 if (!deviceEntity.getStatus().equals(DeviceStatus.ONLINE)) {
			 deviceOperateService.configChannel(deviceEntity);
		 }
		updateDeviceEntity.setStatus(DeviceStatus.ONLINE);
		updateDeviceEntity.setLastUploadLogTime(deviceInfo.getUploadTime());
		updateDeviceEntity.setPeriodic(deviceInfo.getPeriodic());
		deviceDao.update(updateDeviceEntity);
	}

	@Override
	public void configTvCallBack(Callback callback) {
		ConfStatus confStatus = callback.isStatus() ? ConfStatus.UP_TO_DATE : ConfStatus.CONF_FAIL;
		DeviceEntity deviceEntity = new DeviceEntity();
		deviceEntity.setSn(callback.getSn());
		deviceEntity.setConfStatus(confStatus);
		deviceDao.update(deviceEntity);
	}

	@Override
	public PageResponse getMgt(DeviceRequest request) {
		List<DeviceMgtLogEntity> deviceMgtLogEntities = deviceMgtLogDao.selectListByCondition(request.getSn(),
				request.getPage(), request.getPageSize());
		if (CollectionUtils.isEmpty(deviceMgtLogEntities)) {
			return PageResponse.success(0, request.getPageSize(), new ArrayList<>());
		}
		final Integer total = deviceMgtLogDao.selectCountByCondition(request.getSn());
		return PageResponse.success(total, request.getPageSize(), deviceMgtLogEntities);
	}

	@Override
	public Response updateAliasName(String sn, String aliasName) {
		DeviceEntity deviceEntity = new DeviceEntity();
		deviceEntity.setSn(sn);
		deviceEntity.setAliasName(aliasName);
		deviceDao.update(deviceEntity);
		return Response.success();
	}

}